# main.py 监测资金费率

import requests  # 导入requests库，用于发送HTTP请求
import json  # 导入json库，用于处理JSON数据
import time  # 导入time库，用于时间相关操作
from machine import UART,Pin,Timer  # 从machine模块导入UART类，用于串口通信
from wificonnect import wifi_connect,isWifiConnect  # 导入wificonnect模块的wifi_connect函数

# 初始化UART串口，用于与电话模块通信
uart1 = UART(2, baudrate=115200, tx=16, rx=17, timeout=10)

# 加载配置文件
def load_config():
    with open('config.json', 'r') as f:
        return json.load(f)

# 读取配置文件内容
config = load_config()
PHONE_NUMBER = config['phone_number']  # 从配置文件中获取电话号码
BFY_UID = config['bfyUID']  # 定义目标服务器要求的UID

SERVERTIME = 0

leds = []
#初始化点击头状态
def initTouch():
    global pin12, pin19, pin32
    pin12 = Pin(12, Pin.OUT)    # 输出引脚
    pin19 = Pin(19, Pin.OUT)    # 输出引脚
    pin32 = Pin(32, Pin.OUT)    # 输出引脚
    pin12.value(0)              # 设置输出引脚为低电平
    pin19.value(0)              # 设置输出引脚为低电平
    pin32.value(0)              # 设置输出引脚为低电平
    leds.append(pin12)
    leds.append(pin19)
    leds.append(pin32)

#控制点击头
def setLED(p):
    n = int(p)
    for i,v in enumerate(leds):
        v.value(0)
    if n == 0:
        print('led:(0,0,0)',n)
    elif n == 1:
        leds[0].value(1)
        print('led:(0,0,1)',n)
    elif n == 2:
        leds[1].value(1)
        print('led:(0,1,0)',n)
    elif n == 3:
        leds[0].value(1)
        leds[1].value(1)
        print('led:(0,1,1)',n)
    elif n == 4:
        leds[2].value(1)
        print('led:(1,0,0)',n)
    elif n == 5:
        leds[0].value(1)
        leds[2].value(1)
        print('led:(1,0,1)',n)
    elif n == 6:
        leds[1].value(1)
        leds[2].value(1)
        print('led:(1,1,0)',n)
    elif n == 7:
        leds[0].value(1)
        leds[1].value(1)
        leds[2].value(1)
        print('led:(1,1,1)',n)
    else:
        print('led:(0,0,0)',n)
    if reportOKX:
        leds[0].value(0)
    else:
        leds[0].value(1)
def blinkLED(led,times = 5):
    for i in range(times):
        setLED(led)
        time.sleep_ms(300)
        setLED(0)
        time.sleep_ms(300)


# 发送命令到电话模块的函数
def send_cmd(command):
    print(f"Sending command: {command}")
    uart1.write(command + '\r\n')  # 通过串口发送命令

# 测试电话模块是否响应的函数
def ping():
    send_cmd('AT')  # 发送AT命令，用于测试电话模块是否在线

def wx_push(content,title = "资金费率预警"):
    if not isWifiConnect():
        setLED(7)
        return
    url = 'https://apis.bemfa.com/vb/wechat/v1/wechatAlert?uid=%s&device=%s&message=%s'%(BFY_UID,title, content)
    response = requests.get(url)
    if response.status_code == 200:
        print("推送成功")
        setLED(3)
    else:
        print("推送失败")
        setLED(7)


# 挂断电话的函数
def off_call():
    send_cmd('AT+CHUP')  # 发送挂断命令
    print("Phone call ended")


timOBJ = Timer(-1)              #建一个虚拟定时器,来于处理定时挂断电话任务

def onTimerEnd(tim):
    off_call()
    setLED(0)
    tim.deinit()
# 拨打电话的函数
def call_phone(phnum=PHONE_NUMBER):
    if len(phnum) != 11:
        print("Wrong phone number, not 11 digits long")
        return
    print(f"Making a call to: {phnum}")
    send_cmd(f'ATD{phnum};')  # 发送拨号命令
    print("Waiting for the phone to ring...")
    time.sleep(1)  # 等待1秒，让电话开始响铃
    #30秒后挂断电话
    timOBJ.init(period=30000,mode=Timer.ONE_SHOT ,callback=onTimerEnd)
    #接3秒串口数据
    for i in range(30):
        line = uart1.readline()
        if line:
            line = line.decode('utf-8').strip()
            print(line)
            if "ERROR" in line: #打电话失败
                return False
            elif PHONE_NUMBER in line: #电话接通
                print("Phone call connected")
        time.sleep(0.1)  # 短暂等待，避免过度占用CPU
    # off_call()  # 挂断电话

#检查是否有电话打入
isPhoneNum = False
isCallIn = False
ringCount = 0

reportOKX = True

def checkCallIn():
    global isPhoneNum,isCallIn,ringCount,reportOKX
    line = uart1.readline()
    while line:
        if line:
            line = line.decode('utf-8').strip()
            print(line)
            if len(PHONE_NUMBER) <6 or PHONE_NUMBER in line:
                isPhoneNum = True
            if "RING" in line:  # 检测到来电
                print("Incoming call detected=1")
                isCallIn = True
                ringCount += 1
        time.sleep(0.1)
        line = uart1.readline()
    time.sleep(0.1)
    if isPhoneNum and isCallIn and ringCount > 0:
        isPhoneNum = False
        isCallIn = False
        ringCount = 0
        print("Incoming call detected=2")
        off_call()
        reportOKX = not reportOKX
        try:
            if reportOKX:
                print("开始监控")
                wx_push("开始监控")
            else:
                print("停止监控")
                wx_push("停止监控")
        except:
            print("推送失败")
        time.sleep(3)
        setLED(0)
# 监控资金费率的函数
def monitor_funding_rate():
    funding_rate = 0.0  #ok
    binance_rate = 0.0  #binance
    lastRunding = -1
    lastBinance = -1
    delayWget =  0
    while True:
        if not isWifiConnect():
            break
        if delayWget <= 0:
            delayWget = 300   # 5分钟
            funding_rate = getOKX()  # 请求okx的永续合约费率
            time.sleep(1)
            binance_rate = getBinance()
            if funding_rate is not None:
                print(type(funding_rate))
                print("Funding Rate:", "%.6f"%(funding_rate*100))  # 打印 fundingRate 的值
                isPushWX = False
                if lastRunding > 0 and funding_rate < 0: #发送微信推送提醒
                    isPushWX = True
                elif lastRunding == -1 and (funding_rate < 0 or funding_rate >= 0.0006):
                    isPushWX = True
                elif lastRunding > -0.0001 and funding_rate < -0.0001:
                    isPushWX = True
                elif lastRunding > -0.0002 and funding_rate < -0.0002:
                    isPushWX = True
                elif lastRunding > -0.0003 and funding_rate < -0.0003:
                    isPushWX = True
                elif lastRunding < 0.0001 and funding_rate > 0.0001:
                    isPushWX = True
                elif lastRunding < 0.0002 and funding_rate > 0.0002:
                    isPushWX = True
                elif lastRunding < 0.0003 and funding_rate > 0.0003:
                    isPushWX = True
                elif lastRunding < 0.0004 and funding_rate > 0.0004:
                    isPushWX = True
                elif lastRunding < 0.0005 and funding_rate > 0.0005:
                    isPushWX = True
                elif lastRunding < 0.0006 and funding_rate > 0.0006:
                    isPushWX = True
                elif lastBinance != binance_rate:
                    isPushWX = True
                if isPushWX and (lastRunding != 0 or lastBinance != binance_rate):
                    wx_push('binance(%.6f%%25),okx(%.6f%%25),%d'%(binance_rate*100,funding_rate*100,reportOKX))
                    setLED(2)
                    time.sleep(3)
                    blinkLED(2)
                if reportOKX and (funding_rate < -0.0001 and binance_rate < -0.0001) or (funding_rate > 0.0003 and binance_rate > 0.0003):
                        setLED(3)
                        call_phone()  # 如果 fundingRate 负数或大于 0.5，拨打电话
            else:
                print("Failed to retrieve funding rate.")  # 处理获取失败的情况
            lastRunding = funding_rate
            lastBinance = binance_rate
        delayWget -= 1
        time.sleep(1)  #每秒检查一次是否有电话打进来
        checkCallIn()



def main():
    initTouch()
    time.sleep(1)
    blinkLED(1)
    reconnectCount = 10000 # 设置重连次数
    while reconnectCount > 0:
        print("Connecting to Wi-Fi...")  # 打印连接Wi-Fi的提示信息
        if wifi_connect():  # 尝试连接Wi-Fi
            blinkLED(2)
            print("Wi-Fi connected. Monitoring funding rates...")  # Wi-Fi连接成功，开始监控资金费率
            ping()  # 测试电话模块是否在线
            try:
                monitor_funding_rate()  # 开始监控资金费率
            except Exception as e:
                print("Error:", e)
        else:
            print("Wi-Fi connection failed.")  # Wi-Fi连接失败
            blinkLED(3)
        reconnectCount -= 1  # 减少重连次数
        time.sleep(60)  # 等待 60 秒后重连
# 主程序入口
if __name__ == "__main__":
    main()
